<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <title>部门管理系统</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <style>
    body {
      font-family: Arial, sans-serif;
      padding: 20px;
      background-color: #f9f9f9;
    }

    header {
      background-color: #409EFF;
      color: white;
      padding: 16px;
      font-size: 24px;
      margin-bottom: 20px;
      border-radius: 8px;
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    }

    .search-bar {
      margin-bottom: 10px;
    }

    input[type="text"] {
      padding: 6px 10px;
      border: 1px solid #ccc;
      border-radius: 4px;
    }

    button {
      padding: 6px 12px;
      border: none;
      border-radius: 4px;
      cursor: pointer;
    }

    .btn-primary {
      background-color: #409EFF;
      color: white;
    }

    .btn-danger {
      background-color: #f56c6c;
      color: white;
    }

    .btn-cancel {
      background-color: #909399;
      color: white;
    }

    table {
      width: 100%;
      border-collapse: collapse;
      margin-top: 10px;
      background: white;
      border-radius: 8px;
      overflow: hidden;
      box-shadow: 0 2px 8px rgba(0,0,0,0.05);
    }

    th, td {
      border-bottom: 1px solid #f0f0f0;
      padding: 12px;
      text-align: left;
    }

    th {
      background-color: #f2f2f2;
    }

    /* 弹窗样式 */
    .modal-overlay {
      position: fixed;
      top: 0;
      left: 0;
      width: 100vw;
      height: 100vh;
      background-color: rgba(0,0,0,0.3);
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .modal {
      background: white;
      padding: 20px;
      border-radius: 8px;
      width: 300px;
      box-shadow: 0 4px 12px rgba(0,0,0,0.1);
    }

    .modal h3 {
      margin-top: 0;
    }

    .modal input[type="text"] {
      width: 100%;
      box-sizing: border-box;
    }

    .toast {
      position: fixed;
      top: 20px;
      left: 50%;
      transform: translateX(-50%);
      background-color: #67C23A;
      color: white;
      padding: 12px 24px;
      border-radius: 6px;
      box-shadow: 0 2px 8px rgba(0,0,0,0.15);
      z-index: 9999;
      transition: opacity 0.3s ease;
    }

    .toast.error {
      background-color: #F56C6C;
    }
  </style>
</head>
<body>
<div id="app">
  <!-- 顶部提示 -->
  <div v-if="toastMessage" :class="['toast', toastType]">
    {{ toastMessage }}
  </div>

  <header>部门管理系统</header>

  <!-- 搜索栏 -->
  <div class="search-bar">
    <input v-model="searchName" placeholder="搜索部门名" type="text">
    <button class="btn-primary" @click="fetchDepts">搜索</button>
  </div>

  <!-- 添加按钮 -->
  <button class="btn-primary" @click="openAddForm">添加部门</button>

  <!-- 弹窗表单 -->
  <div class="modal-overlay" v-if="showForm">
    <div class="modal">
      <h3>{{ form.id ? '修改部门' : '添加部门' }}</h3>
      <label>
        部门名称：
        <input v-model="form.name" type="text" style="width: 100%; margin-top: 6px; margin-bottom: 12px;">
      </label>
      <div>
        <button class="btn-primary" @click="saveDept">保存</button>
        <button class="btn-cancel" @click="cancelForm">取消</button>
      </div>
    </div>
  </div>

  <!-- 表格 -->
  <table>
    <thead>
    <tr>
      <th>ID</th>
      <th>名称</th>
      <th>创建时间</th>
      <th>更新时间</th>
      <th>操作</th>
    </tr>
    </thead>
    <tbody>
    <tr v-for="dept in filteredDepts" :key="dept.id">
      <td>{{ dept.id }}</td>
      <td>{{ dept.name }}</td>
      <td>{{ dept.createTime }}</td>
      <td>{{ dept.updateTime }}</td>
      <td>
        <button class="btn-primary" @click="editDept(dept)">修改</button>
        <button class="btn-danger" @click="deleteDept(dept.id)">删除</button>
      </td>
    </tr>
    </tbody>
  </table>
</div>

<script>
  const { createApp, ref, computed } = Vue;

  createApp({
    setup() {
      const depts = ref([]);
      const searchName = ref('');
      const showForm = ref(false);
      const form = ref({ id: null, name: '' });
      const toastMessage = ref('');
      const toastType = ref('');

      const showToast = (msg, type = 'success') => {
        toastMessage.value = msg;
        toastType.value = type === 'success' ? '' : 'error';
        setTimeout(() => toastMessage.value = '', 3000);
      };

      const fetchDepts = () => {
        axios.get('/depts')
                .then(res => {
                  depts.value = res.data.data;
                })
                .catch(() => showToast('获取部门失败', 'error'));
      };

      const filteredDepts = computed(() => {
        return depts.value.filter(dept =>
                dept.name.toLowerCase().includes(searchName.value.toLowerCase())
        );
      });

      const openAddForm = () => {
        form.value = { id: null, name: '' };
        showForm.value = true;
      };

      const editDept = (dept) => {
        form.value = { ...dept };
        showForm.value = true;
      };

      const cancelForm = () => {
        showForm.value = false;
      };

      const saveDept = () => {
        const action = form.value.id ? axios.put : axios.post;
        const url = form.value.id ? '/depts' : '/depts';
        action(url, form.value)
                .then(() => {
                  fetchDepts();
                  showForm.value = false;
                  showToast(form.value.id ? '修改成功' : '添加成功');
                })
                .catch(() => showToast('保存失败', 'error'));
      };

      const deleteDept = (id) => {
        if (confirm('确定删除该部门吗？')) {
          axios.delete(`/depts/${id}`)
        .then(() => {
            fetchDepts();
            showToast('删除成功');
          })
                  .catch(() => showToast('删除失败', 'error'));
        }
      };

      fetchDepts();

      return {
        depts,
        searchName,
        filteredDepts,
        showForm,
        form,
        toastMessage,
        toastType,
        fetchDepts,
        openAddForm,
        cancelForm,
        saveDept,
        editDept,
        deleteDept,
      };
    }
  }).mount('#app');
</script>
</body>
</html>